﻿using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using CodeDemon.Models;
using System.Configuration;

namespace SynchSVN
{
	class Program
	{
		static void Main(string[] args)
		{
			ReviewModel model = new ReviewModel();
			var repoList = (from repos in model.DAO.GetSVNRepositories() select repos);


			foreach (var SVNRepo in repoList)
			{

				// TODO: Add Revision to Review Link Table Entry
				StringBuilder sb = new StringBuilder(string.Empty);
				Guid myGuide = System.Guid.NewGuid();
				string ApplicationFilePath = ConfigurationManager.AppSettings["TempDir"].ToString();
				string infoXmlPath = System.IO.Path.Combine(ApplicationFilePath, myGuide.ToString() + ".info");
				using (Process p2 = new Process())
				{
					p2.StartInfo.UseShellExecute = false;
					p2.StartInfo.CreateNoWindow = true;
					p2.StartInfo.FileName = ConfigurationManager.AppSettings["SVNInfoBatch"].ToString();

					p2.StartInfo.Arguments = SVNRepo.RepositoryURL + " " + infoXmlPath;
					p2.Start();
					p2.WaitForExit();
					using (FileStream inputStream = new FileStream(infoXmlPath, FileMode.Open, FileAccess.Read))
					{
						using (StreamReader streamReader = new StreamReader(inputStream))
						{

							while (!streamReader.EndOfStream)
							{
								sb.Append(streamReader.ReadLine() + Environment.NewLine);
							};
							streamReader.Close();
							inputStream.Close();

							// this is a changeset
						}
					}
				}

				XDocument xDoc = XDocument.Parse(sb.ToString(), LoadOptions.None);
				var entry = (from entries in xDoc.Descendants("entry") select entries).FirstOrDefault();
				int currentRevision = Int32.Parse(entry.Attribute("revision").Value);
				File.Delete(infoXmlPath);

				// now we compare

				var dbRev = (from revs in model.DAO.GetRevisionLatest(SVNRepo.RepositoryID) select revs).FirstOrDefault();
				if (dbRev.DatabaseRevision < currentRevision)
				{
					// get that log & process it!
					Guid LogGUID = System.Guid.NewGuid();
					string XmlPath = System.IO.Path.Combine(ApplicationFilePath, LogGUID.ToString() + ".info");
					using (Process p2 = new Process())
					{
						p2.StartInfo.UseShellExecute = false;
						p2.StartInfo.CreateNoWindow = true;
						p2.StartInfo.FileName = ConfigurationManager.AppSettings["SVNLogRangeBatch"].ToString();
						p2.StartInfo.Arguments = (dbRev.DatabaseRevision + 1) + @" " + currentRevision + @" " + SVNRepo.RepositoryURL + " " + XmlPath;
						p2.Start();
						p2.WaitForExit();
					}

					XDocument SvnLog = XDocument.Load(XmlPath);

					foreach (var rev in SvnLog.Descendants("logentry"))
					{
						string revision = rev.Attribute("revision").Value;
						string author = rev.Element("author").Value;
						string logMessage = rev.Element("msg").Value;
						string date = rev.Element("date").Value;
						string Xml = rev.ToString(SaveOptions.DisableFormatting);
						Regex findDefect = new Regex(ConfigurationManager.AppSettings["RegexForDefectInLogMessage"].ToString());
						Match matcher = findDefect.Match(logMessage);
						string defectNumber = matcher.Groups["BUG_ID"].Value;

						if (defectNumber == String.Empty)
						{
							defectNumber = "0";
						}
						if (defectNumber != String.Empty)
						{
							try
							{
								model.DAO.InsertSVNLog(Int32.Parse(revision), author.ToUpperInvariant(), DateTime.Parse(date), logMessage, Xml, Int32.Parse(defectNumber),SVNRepo.RepositoryID);
							}
							catch (System.Exception ex)
							{
								throw;
							}
						}
					}
					File.Delete(XmlPath);
				}
			}
		}
	}
}
